import { checkAll, deleteCart, findCart, getNewCartGoods, insertCart, mergeCart, updateCart } from '@/api/cart'
import Message from '@/components/library/Message'

// 购物车模块
export default {
  namespaced: true,
  state () {
    return {
      // 购物车商品内容
      list: []
    }
  },
  getters: {
    // 有效商品列表
    validList (state) {
      // 有效商品：库存stock大于0 商品有效标识isEffective为true
      // state.list = Array.prototype.slice.call(state.list)
      return state.list.filter(goods => goods.stock > 0 && goods.isEffective)
    },
    // 有效商品总件数
    validTotal (state, getters) {
      // reduce函数用来累计 p是上一次累加的结果 c是当前项 初始值为0
      return getters.validList.reduce((p, c) => p + c.count, 0)
    },
    // 有效商品总金额
    validPrice (state, getters) {
      // 保证浮点数计算的精度
      return getters.validList.reduce((p, c) => p + (c.nowPrice * 100 * c.count) / 100, 0)
    },
    // 无效商列表
    invalidList (state) {
      return state.list.filter(goods => goods.stock <= 0 || !goods.isEffective)
    },
    // 已选商品列表
    selectedList (state, getters) {
      return getters.validList.filter(goods => goods.selected)
    },
    // 已选商品总件数
    selectedTotal (state, getters) {
      return getters.selectedList.reduce((p, c) => p + c.count, 0)
    },
    // 已选商品总金额
    selectedPrice (state, getters) {
      return getters.selectedList.reduce((p, c) => p + (c.nowPrice * 100 * c.count) / 100, 0)
    },
    // 是否全选
    isCheckAll (state, getters) {
      return getters.validList.length !== 0 && getters.selectedList.length === getters.validList.length
    }
  },
  mutations: {
    // 加入购物车
    addCart (state, goods) {
      // 约定加入购物车字段必须和后端保持一致
      // 他们是id skuId name attrsText price  picture selected...
      // 插入数据的规则：
      // 先找是否有相同的商品，若有则增加数量，若有相同商品，先查询数量，然后再合并累加到payload上，再保存
      // 没有相同商品，保存到最新位置
      const sameIndex = state.list.findIndex(item => item.skuId === goods.skuId)
      // 找到
      if (sameIndex >= 0) {
        // console.log('找到了')
        const count = state.list[sameIndex].count
        goods.count += count
        // 删除原来的
        state.list.splice(sameIndex, 1)
      }
      // 增加新的(在顶部追加)
      state.list.unshift(goods)
    },
    // 修改本地购物车商品(根据商品的最新数据修改state里的商品)
    updateCart (state, goods) {
      // goods商品信息：nowPrice stock isEffective
      // goods商品对象的字段不固定，对象中有哪些字段就改哪些字段
      // goods商品对象必须有SKUID
      const updateGoods = state.list.find(item => item.skuId === goods.skuId)// 拿到要改的商品
      for (const key in goods) {
        if (goods[key] !== undefined && goods[key] !== null && goods[key] !== '') {
          updateGoods[key] = goods[key]
        }
      }
    },
    // 删除购物车商品
    deleteCart (state, skuId) {
      const index = state.list.findIndex(item => item.skuId === skuId)
      state.list.splice(index, 1)
    },
    // 设置购物车
    setCart (state, payload) {
      // payload为空数组 就是清空购物车
      state.list = payload
    }
  },
  actions: {
    // 加入购物车
    addCart (ctx, goods) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          console.log('已登录')
          insertCart({ skuId: goods.skuId, count: goods.count }).then(() => {
            return findCart()
          }).then(data => {
            ctx.commit('setCart', data.result)
            Message({ text: '添加购物车成功', type: 'success' })
            resolve()
          })
        } else {
          // 未登录
          ctx.commit('addCart', goods)
          Message({ text: '添加本地购物车成功', type: 'success' })
          resolve()
        }
      })
    },
    // 获取商品列表
    findCart (ctx) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          findCart().then(data => {
            // ctx.commit('setCart', data.result)
            ctx.state.list = data.result
          })
        } else {
          // 未登录
          // 同时发送请求（有几件商品就否发送几个请求 等所有请求成功 一并去修改本地购物车数据）
          // Promise.all([promise数组]).then((dataList)=>{}) 同时发送请求 得到所有请求结果
          // Promise.resolve() Promise.reject() new Promise()
          // Promise.race([promise数组]).then((dataList)=>{}) 同时发送请求 最快的请求成功 得到成功结果
          const promiseArr = ctx.state.list.map(goods => {
            return getNewCartGoods(goods.skuId)
          })
          // dataList代表成功结果的集合 数据顺序和promiseArr顺序一致 它又是根据state。list而来
          Promise.all(promiseArr).then(dataList => {
            // 更新本地购物车
            dataList.forEach((data, i) => {
              ctx.commit('updateCart', { skuId: ctx.state.list[i].skuId, ...data.result })
            })
            // 调用resolve()表示操作结束
            resolve()
          })
        }
      })
    },
    // 删除购物车
    deleteCart (ctx, payload) {
      // 单条删除 payload就是skuId
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          deleteCart([payload]).then(() => {
            return findCart()
          }).then(data => {
            ctx.commit('setCart', data.result)
            resolve()
          })
        } else {
          ctx.commit('deleteCart', payload)
          resolve()
        }
      })
    },
    // 批量删除购物车,也支持清空无效商品
    batchDeleteCart (ctx, isClear) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          const ids = ctx.getters[isClear ? 'invalidList' : 'selectedList'].map(item => item.skuId)
          deleteCart(ids).then(() => {
            return findCart()
          }).then(data => {
            ctx.commit('setCart', data.result)
            resolve()
          })
        } else {
          // 未登录 找出未选中的列表 遍历调用删除的mutations
          // isClear为true删除失效商品列表 否则是选中的商品列表
          ctx.getters[isClear ? 'invalidList' : 'selectedList'].forEach(item => {
            ctx.commit('deleteCart', item.skuId)
          })
          resolve()
        }
      })
    },
    // 修改购物车(选中状态 数量)
    updateCart (ctx, payload) {
      // payload需要skuId 可能有selected count
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          updateCart(payload).then(() => {
            return findCart()
          }).then(data => {
            ctx.commit('setCart', data.result)
            resolve()
          })
        } else {
          // 未登录
          ctx.commit('updateCart', payload)
          resolve()
        }
      })
    },
    // 全选与取消全选
    checkAllCart (ctx, selected) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          checkAll({ selected }).then(() => {
            return findCart()
          }).then(data => {
            ctx.commit('setCart', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 让有效商品列表的所有状态与全选按钮状态selected保持一致
          ctx.getters.validList.forEach(goods => {
            ctx.commit('updateCart', { skuId: goods.skuId, selected })
          })
          resolve()
        }
      })
    },
    // 修改规格
    updateCartSku (ctx, { oldSkuId, newSku }) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已经登录
          const oldGoods = ctx.state.list.find(item => item.skuId === oldSkuId)
          console.log([oldGoods.skuId])
          deleteCart([oldGoods.skuId]).then(() => {
            return insertCart({ skuId: newSku.skuId, count: oldGoods.count })
          }).then(() => {
            return findCart()
          }).then(data => {
            ctx.commit('setCart', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 1.找出旧的商品信息
          // 2.删除旧的商品信息
          // 3.根据新的sku和旧的商品信息 合并成一条新的购物车商品数据
          // 4.添加新的商品信息
          const oldGoods = ctx.state.list.find(item => item.skuId === oldSkuId)
          ctx.commit('deleteCart', oldSkuId)
          // 将新商品数据解构
          const { skuId, price: nowPrice, specsText: attrsText, inventory: stock } = newSku
          // 合并生成新商品信息
          const newGoods = { ...oldGoods, skuId, nowPrice, attrsText, stock }
          ctx.commit('addCart', newGoods)
          resolve()
        }
      })
    },
    async mergeCart (ctx) {
      const cartList = ctx.state.list.map(goods => {
        return {
          skuId: goods.skuId,
          selected: goods.selected,
          count: goods.count
        }
      })
      await mergeCart(cartList)
      // 合并成功 清空本地购物车
      ctx.commit('setCart', [])
    }
  }
}
